﻿using DevelopTool.Model.Enums;
using HtmlAgilityPack;
using Markdig;
using Markdig.SyntaxHighlighting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace DevelopTool.Common
{
    /// <summary>
    /// Markdown帮助类
    /// https://github.com/xoofx/markdig
    /// </summary>
    public class MarkdownHelper
    {

        /// <summary>
        /// 将Markdown转换为html
        /// </summary>
        /// <param name="markdownContent"></param>
        /// <returns></returns>
        public static string MarkdownToHtml(string markdownContent, bool isCodeHighlighting, bool replaceUnsupportedTags = true)
        {
            MarkdownPipelineBuilder pipeline = new MarkdownPipelineBuilder()
                .UseAdvancedExtensions()
                .UseEmojiAndSmiley()
                .UseGlobalization()
                .UsePreciseSourceLocation()
                .UseSmartyPants()
                .UseBootstrap();

            //是否代码高亮
            if (isCodeHighlighting) pipeline.UseSyntaxHighlighting();

            string html = Markdig.Markdown.ToHtml(markdownContent, pipeline.Build());

            // 替换IE11不支持的标签
            if (replaceUnsupportedTags)
                html = ReplaceUnsupportedTags(html);

            return html;
        }

        public static string MarkdownFileToHtml(string filePath, bool isCodeHighlighting, bool replaceUnsupportedTags = true)
        {
            string markdownContent = File.ReadAllText(filePath);//读取文件内容

            string html = MarkdownToHtml(markdownContent, isCodeHighlighting, replaceUnsupportedTags);

            if (string.IsNullOrEmpty(filePath)) return html;

            if (!File.Exists(filePath)) return html;

            // 加载HTML字符串
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html);

            //获取所有img标签
            var imgs = doc.DocumentNode.SelectNodes("//img");

            if(imgs==null) return html;

            //遍历img标签集合
            foreach (HtmlNode img in imgs)
            {
                string oldSrc = img.Attributes["src"].Value;

                oldSrc = StringHelper.UrlDecode(oldSrc);//url解码
                oldSrc = oldSrc.Replace("/", @"\");//替换为反斜杠
                oldSrc = oldSrc.Replace(@".\", "");//去除第一个.
                string newSrc = Path.Combine(Path.GetDirectoryName(filePath), oldSrc);//拼接新路径
                img.SetAttributeValue("src", newSrc);//设置html img标签的src值
            }

            return doc.DocumentNode.OuterHtml;
        }


        /// <summary>
        /// 去除markdown标签，返回纯文本
        /// </summary>
        /// <param name="markdownContent"></param>
        /// <returns></returns>
        public static string MarkdownToPlainText(string markdownContent)
        {
            return Markdig.Markdown.ToPlainText(markdownContent);
        }


        /// <summary>
        /// 判断字符串是Markdown还是HTML，可能不准确
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns>返回"Markdown"或"HTML"或"Unknown"</returns>
        public static ContentType GetContentType(string input)
        {
            try
            {
                //检测是否为文件路径
                if (File.Exists(input))
                {
                    return ContentType.FilePath;
                }

                // 检测是否是Markdown
                else if (IsMarkdown(input))
                {
                    return ContentType.Markdown;
                }

                // 检测是否是HTML
                else if (IsHtml(input))
                {
                    return ContentType.HTML;
                }

                else
                {
                    return ContentType.Unknown;
                }
            }
            catch (Exception)
            {
                return ContentType.Unknown;
            }
        }


        /// <summary>
        /// 判断字符串是否为HTML
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns>如果是HTML则返回true，否则返回false</returns>
        private static bool IsHtml(string input)
        {
            // 检测常见的HTML标签
            string htmlPattern = @"</?([a-z][a-z0-9]*)\b[^>]*>";
            if (Regex.IsMatch(input, htmlPattern, RegexOptions.IgnoreCase))
            {
                return true;
            }

            // 检测是否有复杂的HTML结构
            string complexHtmlPattern = @"<(html|head|body|meta|style|script|div|span|table|tr|td|img|a)(\s[^>]*)?>";
            return Regex.IsMatch(input, complexHtmlPattern, RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 判断字符串是否为Markdown
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns>如果是Markdown则返回true，否则返回false</returns>
        private static bool IsMarkdown(string input)
        {
            // 常用的Markdown语法检测
            string[] markdownPatterns = new string[]
            {
            @"^\s{0,3}(#{1,6})\s+.+",  // 标题
            @"(\*\*|__)(.*?)\1",        // 粗体
            @"(\*|_)(.*?)\1",           // 斜体
            @"\[(.*?)\]\((.*?)\)",      // 链接
            @"(`{1,3})(.*?)\1",         // 行内代码块
            @"^\s{0,3}[-\*\+]\s+",      // 无序列表
            @"^\s{0,3}\d+\.\s+"         // 有序列表
            };

            foreach (var pattern in markdownPatterns)
            {
                if (Regex.IsMatch(input, pattern, RegexOptions.Multiline))
                {
                    return true;
                }
            }

            return false;
        }


        /// <summary>
        /// // 替换IE11不支持的标签
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        private static string ReplaceUnsupportedTags(string html)
        {
            // 定义不支持的标签及其替代方案的映射
            var replacements = new Dictionary<string, string>
            {
                { "details", "ul" },
                { "summary", "li" },

                { "dialog", "div" },

                { "main", "section" },

                { "menu", "ul" },
                { "menuitem", "li" },
            };

            // 构建正则表达式模式，匹配不支持的标签
            string pattern = $@"<\/?({string.Join("|", replacements.Keys)})\b([^>]*)?>";

            // 使用正则表达式进行替换
            StringBuilder sb = new StringBuilder();
            int lastIndex = 0;

            foreach (Match match in Regex.Matches(html, pattern, RegexOptions.IgnoreCase))
            {
                string tagName = match.Groups[1].Value.ToLower();
                string attributes = match.Groups[2].Value;

                // 查找替代标签，如果没有找到则保留原标签
                string replacementTag = replacements.ContainsKey(tagName) ? replacements[tagName] : tagName;

                // 将替换后的标签添加到结果中
                sb.Append(html.Substring(lastIndex, match.Index - lastIndex));
                if (match.Value.StartsWith("</"))
                {
                    sb.Append($"</{replacementTag}>");
                }
                else
                {
                    sb.Append($"<{replacementTag}{attributes}>");
                }

                lastIndex = match.Index + match.Length;
            }

            // 添加剩余的HTML内容到结果中
            sb.Append(html.Substring(lastIndex));

            return sb.ToString();
        }
    }


}
